package com.syh.jn.scm.domain.supplier.entity.base.goods;


import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.util.validator.ValidationUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.domain.AbstractSimpleAggregate;
import com.syh.jn.scm.domain.supplier.repository.base.goods.GoodsCategoryReadRepository;
import com.syh.jn.scm.domain.supplier.repository.base.goods.GoodsCategoryRepository;
import com.syh.jn.scm.domain.supplier.repository.base.goods.GoodsRepository;
import com.syh.jn.scm.dto.supplier.base.goods.goodsCate.GoodsCategoryMto;
import com.syh.jn.scm.dto.supplier.base.goods.goodsCate.GoodsCategorySto;
import com.syh.jn.scm.exception.BusinessException;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 商品分类
 */
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class GoodsCategory extends AbstractSimpleAggregate<Long> {

  /**
   * 状态（-1：停用 1：启用）
   */
  private Short status;
  /**
   * 上级分类id
   */
  private Long supId;
  /**
   * 归属id
   */
  private Long businessEntityId;
  /**
   * 父类目录
   */
  private String catalogCode;
  /**
   * 分类编码
   */
  private String code;
  /**
   * 类别名称
   */
  private String name;
  /**
   * 排序等级
   */
  private Integer orderLevel;
  /**
   * 分类等级
   */
  private Integer cateLevel;
  /**
   * 父分类
   */
  private GoodsCategory fatherCategorys;
  /**
   * 子分类
   */
  private List<GoodsCategory> subCategorys;


  public GoodsCategory(GoodsCategorySto sto) {
    ExtAssert.notNull(sto, "对象为空");
    ValidationUtils.validate(sto);

    this.createTimeStamp = System.currentTimeMillis();
    this.status = 1;
    this.name = sto.getName();
    this.orderLevel = sto.getOrderLevel();
    this.businessEntityId = sto.getBusinessEntityId();
    this.initDefault();
    //判断父级分类
    if (sto.getSupId() == null) {
      this.cateLevel = 0;
      this.supId = Long.valueOf("0");
    } else {
      this.supId = sto.getSupId();
      GoodsCategoryReadRepository goodsCateQuery = (GoodsCategoryReadRepository) SpringContextUtils.getBean("goodsCategoryRepositoryImpl");
      GoodsCategory fatherGoodsCate = goodsCateQuery.getById(this.supId);
      ExtAssert.notNull(fatherGoodsCate, "父级分类不存在");
      if (!fatherGoodsCate.getStatus().equals(Short.valueOf("1"))) {
        throw new BusinessException("父级分类处于停用状态");
      }
      this.cateLevel = fatherGoodsCate.getCateLevel() + 1;
//      this.code = fatherGoodsCate.getCode() + "-" + "0001";
    }
  }

  public void modify(GoodsCategoryMto mto) {
    ExtAssert.notNull(mto, "对象为空");
    ValidationUtils.validate(mto);
    ExtBeanUtils.copyProperties(mto, this, false);
    //判断父级分类
    if (mto.getSupId() != null && mto.getSupId().intValue() > 0) {
      isFatherCate(mto.getId(), mto.getSupId());
      GoodsCategoryReadRepository goodsCateQuery = (GoodsCategoryReadRepository) SpringContextUtils.getBean(GoodsCategoryReadRepository.class);
      GoodsCategory fatherCategory = goodsCateQuery.getById(this.supId);
      ExtAssert.notNull(fatherCategory, "父级分类不存在");
      if (!fatherCategory.getStatus().equals(Short.valueOf("1"))) {
        throw new BusinessException("父级分类处于停用状态");
      }
      this.cateLevel = fatherCategory.getCateLevel() + 1;
    } else {
      this.cateLevel = 0;
      this.supId = Long.valueOf("0");
    }
    this.lastUpdateTimeStamp = System.currentTimeMillis();
  }

  /**
   * 递归判断不能是自己的父类或者父类的父类
   */
  private void isFatherCate(Long id, Long supId) {
    GoodsCategoryReadRepository goodsCateQuery = (GoodsCategoryReadRepository) SpringContextUtils.getBean(GoodsCategoryReadRepository.class);
    GoodsCategory sup = goodsCateQuery.getById(supId);
    if (sup != null) {
      if (id.equals(sup.getId())) {
        throw new BusinessException("父类不能是自己或者自己的子类");
      }
      isFatherCate(id, sup.getSupId());
    }
  }

  /**
   * 启用分类
   */
  public void enabled() {
    GoodsCategoryRepository goodsCateQuery = (GoodsCategoryRepository) SpringContextUtils.getBean(GoodsCategoryRepository.class);
    this.status = 1;
    if (!Long.valueOf("0").equals(this.supId)) {
      this.fatherCategorys = getAllFatherCates(goodsCateQuery, this.supId);
      updateFatherCates(this.fatherCategorys, this.status);
    }
  }

  /**
   * 停用分类
   */
  public void disabled() {
    GoodsCategoryRepository goodsCateQuery = (GoodsCategoryRepository) SpringContextUtils.getBean(GoodsCategoryRepository.class);
    GoodsRepository goodsQuery = (GoodsRepository) SpringContextUtils.getBean(GoodsRepository.class);

    this.subCategorys = goodsCateQuery.getList(Wrapper.build().append(Restrictions.rightLike("catalogCode", this.catalogCode)));
    this.subCategorys.forEach(subCate -> {
      if (goodsQuery.goodsExistsByColumn("categoryId", subCate.getId())) {
        List<Goods> queryList = goodsQuery.getList(Wrapper.build().append(Restrictions.eq("categoryId", subCate.getId())));
        queryList.forEach(good -> {
          if (good.getStatus() == 1)
            throw new BusinessException("该分类或所属子分类下的商品正在使用，停用失败！");
        });
      }
    });
    this.status = -1;
    updateSubCates(this.subCategorys, this.status);
  }

  /**
   * 数据销毁
   */
  public void destroy() {

    GoodsCategoryRepository goodsCateQuery = (GoodsCategoryRepository) SpringContextUtils.getBean(GoodsCategoryRepository.class);
    GoodsRepository goodsQuery = (GoodsRepository) SpringContextUtils.getBean(GoodsRepository.class);
    if (goodsCateQuery.haveSubCates(id)) {
      throw new BusinessException("该分类存在子分类，删除失败！");
    }
    if (goodsQuery.goodsExistsByColumn("categoryId", id)) {
      throw new BusinessException("该分类已经拥有商品，删除失败！");
    }

  }

  /**
   * 获取所有停用的父分类
   */
  private GoodsCategory getAllFatherCates(GoodsCategoryRepository goodsCateQuery, Long id) {
    GoodsCategory fatherCates = goodsCateQuery.getById(id);
    if (!Long.valueOf("0").equals(fatherCates.getSupId()) && !fatherCates.getStatus().equals(Short.valueOf("1"))) {
      fatherCates.setFatherCategorys(getAllFatherCates(goodsCateQuery, fatherCates.getSupId()));
    }
    return fatherCates;
  }

  /**
   * 停用子分类
   */
  public void updateSubCates(List<GoodsCategory> subCates, Short status) {
    subCates.forEach(subCate -> {
      subCate.status = status;
    });
  }

  /**
   * 启用父分类
   */
  public void updateFatherCates(GoodsCategory fatherCates, Short status) {
    fatherCates.status = status;
    if (fatherCates.fatherCategorys != null) {
      updateFatherCates(fatherCates.fatherCategorys, status);
    }
  }
}
